package moon.excel;

import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import moon.excel.reader.IExcelReader;
import moon.util.StringUtils;

/**
 * excel操作基础封装
 */
 public class ExcelImportWrapper {
	public static final Logger LOGGER = LoggerFactory.getLogger(ExcelImportWrapper.class);
	private Workbook wb;
	/** 用于读取excel */
	private IExcelReader excelReader;

	/**
	 * 
	 * @param type  文件类型 xlsx或xls
	 * @param input excel文件输入流
	 */
	public ExcelImportWrapper(IExcelReader excelReader) {
		this.excelReader = excelReader;
		if (excelReader instanceof IObgainWorkbook) {
			wb = ((IObgainWorkbook) excelReader).getWorkbook();
		}
	}

	/***
	 * 获取Workbook 主要用于写入
	 * 
	 * @return
	 */
	public Workbook getWorkbook() {
		if (wb == null) {
			throw new UnsupportedOperationException("不支持该操作");
		}
		return wb;
	}

	/**
	 * 获取已经存在的sheet
	 * 
	 * @param name sheet名称
	 * @return
	 */
	public Sheet getSheet(String name) {
		if (StringUtils.isBlank(name)) {
			throw new ExcelWraperException("sheet名称不能为空");
		}
		Sheet sheet = getWorkbook().getSheet(name);
		return sheet;
	}

	/***
	 * 获取已经存在的sheet
	 * 
	 * @param sheetIndex sheet索引
	 * @return
	 */
	public Sheet getSheet(int sheetIndex) {
		if (sheetIndex < 0) {
			throw new ExcelWraperException("sheet索引必须大于等于0");
		}
		Sheet sheet = getWorkbook().getSheetAt(sheetIndex);
		return sheet;
	}

	/**
	 * 从某一行开始读取所有数据，起始索引位置为0
	 * 
	 * @param sheetIndex     sheet索引
	 * @param columnEndIndex 哪一列索引结束
	 * @param interceptor    每读取一行数据，调用一次
	 */
	public void readSheet(int sheetIndex, int columnEndIndex, IRecordInterceptor<Object[]> interceptor) {
		excelReader.readSheet(sheetIndex, 0, 0, columnEndIndex, null, interceptor);
	}

	/**
	 * 从某一行开始读取所有数据，起始索引位置为0
	 * 
	 * @param sheetIndex       sheet索引
	 * @param rowBeginIndex    哪一行索引开始
	 * @param columnBeginIndex 哪一列索引开始
	 * @param columnEndIndex   哪一列索引结束
	 * @param classs           每一列数据的类型，根据所填入的类型自动进行数据类型转换
	 * @param interceptor      每读取一行数据，调用一次
	 */
	public void readSheet(int sheetIndex, int rowBeginIndex, int columnBeginIndex, int columnEndIndex, Class<?>[] classs, IRecordInterceptor<Object[]> interceptor) {
		excelReader.readSheet(sheetIndex, rowBeginIndex, columnBeginIndex, columnEndIndex, classs, interceptor);
	}

	/**
	 * 读取某些行数据
	 * 
	 * @param sheetIndex     sheet索引
	 * @param columnEndIndex 哪一列索引结束
	 * @param rowIndexs      需要读取的行索引
	 * @param interceptor    每读取一行数据，调用一次
	 */
	public void readSheet(int sheetIndex, int columnEndIndex, int[] rowIndexs, IRecordInterceptor<Object[]> interceptor) {
		excelReader.readSheet(sheetIndex, 0, columnEndIndex, rowIndexs, null, interceptor);
	}

	/**
	 * 读取某些行数据
	 * 
	 * @param sheetIndex       sheet索引
	 * @param columnBeginIndex 哪一列索引开始
	 * @param columnEndIndex   哪一列索引结束
	 * @param rowIndexs        需要读取的行索引
	 * @param classs           每一列数据的类型，根据所填入的类型自动进行数据类型转换
	 * @param interceptor      每读取一行数据，调用一次
	 */
	public void readSheet(int sheetIndex, int columnBeginIndex, int columnEndIndex, int[] rowIndexs, Class<?>[] classs, IRecordInterceptor<Object[]> interceptor) {
		excelReader.readSheet(sheetIndex, columnBeginIndex, columnEndIndex, rowIndexs, classs, interceptor);
	}

	/**
	 * 读取某一行数据
	 * 
	 * @param sheetIndex     sheet索引
	 * @param rowIndex       需要读取的行索引
	 * @param columnEndIndex 哪一列索引结束
	 * @return
	 */
	public Object[] readRow(int sheetIndex, int rowIndex, int columnEndIndex) {
		return excelReader.readRow(sheetIndex, rowIndex, 0, columnEndIndex, null);
	}

	/**
	 * 读取行数据
	 * 
	 * @param sheetIndex       sheet索引
	 * @param rowIndex         需要读取的行索引
	 * @param columnBeginIndex 哪一列索引开始
	 * @param columnEndIndex   哪一列索引结束
	 * @param classs           每一列数据的类型，根据所填入的类型自动进行数据类型转换
	 * @return
	 */
	public Object[] readRow(int sheetIndex, int rowIndex, int columnBeginIndex, int columnEndIndex, Class<?>[] classs) {
		return excelReader.readRow(sheetIndex, rowIndex, columnBeginIndex, columnEndIndex, classs);
	}

	/***
	 * 判断excel是否可写
	 * 
	 * @return
	 */
	public boolean isWriteable() {
		try {
			getWorkbook();
		} catch (Exception e) {
			return false;
		}
		return true;
	}

}
